home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 30
/
Aminet 30 (1999)(Schatztruhe)[!][Apr 1999].iso
/
Aminet
/
gfx
/
show
/
mpeg2decodeWOS.lha
/
mpeg2decode
/
src
/
amidisplay.c
next >
Wrap
C/C++ Source or Header
|
1999-02-25
|
57KB
|
2,069 lines
/* amidisplay.c, Amiga interface */
/* Copyright (C) 1996, MPEG Software Simulation Group. All Rights Reserved. */
/*
* Disclaimer of Warranty
*
* These software programs are available to the user without any license fee or
* royalty on an "as is" basis. The MPEG Software Simulation Group disclaims
* any and all warranties, whether express, implied, or statuary, including any
* implied warranties or merchantability or of fitness for a particular
* purpose. In no event shall the copyright-holder be liable for any
* incidental, punitive, or consequential damages of any kind whatsoever
* arising from the use of these programs.
*
* This disclaimer of warranty extends to the user of these programs and user's
* customers, employees, agents, transferees, successors, and assigns.
*
* The MPEG Software Simulation Group does not represent or warrant that the
* programs furnished hereunder are free of infringement of any third-party
* patents.
*
* Commercial implementations of MPEG-1 and MPEG-2 video, including shareware,
* are subject to royalty fees to patent holders. Many of these patents are
* general enough such that they are unavoidable regardless of implementation
* design.
*
*/
#ifdef DISPLAY
/* the Xlib interface is closely modeled after
* mpeg_play 2.0 by the Berkeley Plateau Research Group
*/
#include <stdio.h>
#include <stdlib.h>
#include "config.h"
#include "global.h"
#define CYBERGFXNAME "cybergraphics.library"
#define CYBERGFXVERSION 40L
#include<string.h>
#include<dos.h>
#include<exec/exec.h>
#include<proto/exec.h>
#include<dos/dos.h>
#include<proto/dos.h>
#include<graphics/gfx.h>
#include<proto/graphics.h>
#include<intuition/intuition.h>
#include<proto/intuition.h>
#include<proto/asl.h>
#include<cybergraphics/cybergraphics.h>
#ifdef STORM
#include <clib/cybergraphics_protos.h>
#include <powerpc/powerpc.h>
#include <clib/powerpc_protos.h>
int bus_MHz=60;
int bus_clock=60000000;
double tb_scale_lo;
double tb_scale_hi;
extern int wb;
#else
#include<proto/cybergraphics.h>
#endif
struct RastPort *rp;
#ifdef STORM
#include <clib/cybergraphics_protos.h>
#include <clib/chunkyppc_protos.h>
struct Library *ChunkyPPCBase;
#else
#include<proto/cybergraphics.h>
#endif
#ifdef STORM
struct TagItem helpbuf[3];
int direct=1;
UBYTE *address;
int bpr;
int opt=0;
#endif
/* Amiga prototypes */
struct Library *CyberGfxBase = NULL;
struct Window *displayWindow = NULL;
struct Screen *displayScreen = NULL;
struct RastPort *tempRastPort = NULL;
void *Ximage_Ptr, *Ximage_Ptr2;
void c2p1x1_8_c5_ppc(void *chunky, void *bitplanes,
int chunkyx, int chunkyy,
int xoffset, int yoffset,
int bitplanesize);
int __amiga_exit(void);
void __amiga_checkdisplay(void);
struct BitMap displayBitMap;
int displayIsOpen = FALSE;
int displayIsNative = TRUE;
/* private prototypes */
static void Display_Image _ANSI_ARGS_((void *Ximage_Ptr, unsigned char *Dithered_Image));
static void Dither_Frame _ANSI_ARGS_((unsigned char *src[]));
static void Dither_Top_Field _ANSI_ARGS_((unsigned char *src[], unsigned char *dst));
static void Dither_Bottom_Field _ANSI_ARGS_((unsigned char *src[], unsigned char *dst));
static void Dither_Top_Field420 _ANSI_ARGS_((unsigned char *src[],
unsigned char *dst));
static void Dither_Bottom_Field420 _ANSI_ARGS_((unsigned char *src[],
unsigned char *dst));
/* local data */
static unsigned char *Dithered_Image = NULL, *Dithered_Image2 = NULL, *Doubled_Image = NULL;
static unsigned char Y_Table[256+16];
static unsigned char Cb_Table[128+16];
static unsigned char Cr_Table[128+16];
static unsigned char Pixel[256];
/* connect to server, create and map window,
* allocate colors and (shared) memory
*/
#ifndef STORM
struct Library *TimerBase = NULL;
struct timerequest *TimerIO = NULL;
struct MsgPort *IDCMP = NULL;
struct MsgPort *TimerMP = 0;
#else
void ppctimer(unsigned int[2]);
#endif
void IO_StartupTimer (void)
{
// Ripped out of sourcecode of AmiHeretic...
#ifdef STORM
struct TagItem ppcinfo[2]={GETINFO_BUSCLOCK,0,0,0};
GetInfo(ppcinfo);
bus_MHz=ppcinfo[0].ti_Data/(1000*1000);
bus_clock=ppcinfo[0].ti_Data;
tb_scale_lo = ((double)(bus_clock >> 2)) / 35.0;
tb_scale_hi = (4.294967296E9 / (double)(bus_clock >> 2)) * 35.0;
#else
TimerMP = CreateMsgPort();
if (!TimerMP)
I_Error("I_InitTimer: Can't create timer message port");
TimerIO = (struct timerequest *)CreateExtIO(TimerMP, sizeof(struct timerequest));
if (!TimerIO)
I_Error("I_InitTimer: Can't create timer IO");
if (OpenDevice((UBYTE *)TIMERNAME, UNIT_MICROHZ, (struct IORequest *)TimerIO, 0l) != 0)
I_Error("I_InitTimer: Can't open timer.device");
TimerBase = (struct Library *)TimerIO->tr_node.io_Device;
#endif
}
void IO_ShutdownTimer(void)
{
// Ripped out of sourcecode of AmiHeretic...
#ifndef STORM
if (TimerIO) {
CloseDevice((struct IORequest *)TimerIO);
DeleteExtIO((struct IORequest *)TimerIO);
TimerIO = 0;
TimerBase = 0;
}
if (TimerMP) {
DeleteMsgPort(TimerMP);
TimerMP = 0;
}
#endif
}
long frames=0;
long secs=0;
#ifdef STORM
void video_do_fps()
{
// Ripped out of Source-Code of AmiHeretic, using 68k source
// if STORM is not defined... small mod's, as mpeg2decode
// uses intuition, and not rtgmaster which AmiHeretic is using...
int x;
static unsigned int start_time[2] = {0, 0};
unsigned int end_time[2];
char msg[4];
ppctimer (end_time);
if (end_time[1] >= start_time[1])
x = (((end_time[1] - start_time[1]) << 2) / bus_MHz);
else
x = (((end_time[1] - start_time[1]) << 2) / bus_MHz + 1000000);
if (x != 0) {
x = (1000000 + (x >> 1)) / x; /* round to nearest */
msg[0] = (x % 1000) / 100 + '0';
msg[1] = (x % 100) / 10 + '0';
msg[2] = (x % 10) + '0';
msg[3] = '\0';
Move(rp,Coded_Picture_Width*Double_Pixels-24,6);
Text(rp,msg,strlen(msg));
}
start_time[1] = end_time[1];
frames+=x;
secs+=1;
}
#else
void video_do_fps()
{
static struct timeval start;
static int init = 0;
struct timeval end, tmp;
char msg[4];
unsigned long x;
if (init == 0) {
init = 1;
GetSysTime(&start);
return;
}
GetSysTime(&end);
SubTime((struct timeval *)&end, (struct timeval *)&start);
x = (unsigned long)((float)frame++/(float)end.tv_secs);
msg[0] = (x % 1000) / 100 + '0';
msg[1] = (x % 100) / 10 + '0';
msg[2] = (x % 10) + '0';
msg[3] = '\0';
Move(rp,Coded_Picture_Width*Double_Pixels-24,6);
Text(rp,msg,strlen(msg));
frames+=x;
secs+=1;
}
#endif
#ifdef STORM
struct TagItem asltags[]=
{0,0
};
UBYTE *colarray1;
unsigned long WBColorTable[3*256+2],ColorTable[3*256+2];
UBYTE transtable[256];
UBYTE *wbcolors;
#include <graphics/rastport.h>
int pen_obtained=0;
void LoadRGBRtg(struct Window *MyWindow, ULONG Table[])
{
// Slightly modified version of the rtgmaster function,
// taken out of rtgmaster source code...
struct TagItem EmptyTags[] =
{
TAG_DONE,0
};
int i,r,g,b;
unsigned char *p;
struct ViewPort *VPort;
struct Window *Window;
struct ColorMap *ColorMap;
ColorMap = MyWindow->WScreen->ViewPort.ColorMap;
VPort = &MyWindow->WScreen->ViewPort;
if (!(pen_obtained))
{
WBColorTable[0] = 0x01000000;
WBColorTable[3*256+1] = 0;
GetRGB32(ColorMap,0,256,WBColorTable+1);
for (i=0;i<(3*256+2);i++)
ColorTable[i] = WBColorTable[i];
for (i=0; i<256; i++)
{
r = Table[3*i+1];
g = Table[3*i+2];
b = Table[3*i+3];
r=r&0xFF000000;
g=g&0xFF000000;
b=b&0xFF000000;
transtable[i] = ObtainBestPenA(ColorMap,r,g,b,EmptyTags);
}
}
for (i=0; i<256; i++)
{
ColorTable[3*transtable[i]+1] = Table[3*i+1];
ColorTable[3*transtable[i]+2] = Table[3*i+2];
ColorTable[3*transtable[i]+3] = Table[3*i+3];
}
LoadRGB32(VPort,ColorTable);
pen_obtained = TRUE;
}
#endif
#ifdef STORM
void Initialize_Display_Process(char *name)
#else
void Initialize_Display_Process(name)
char *name;
#endif
{
int crv, cbu, cgu, cgv;
int Y, Cb, Cr, R, G, B;
int i;
unsigned char *temp;
ULONG mycolors[770];
displayIsOpen = TRUE;
displayBitMap.Planes[0]=0;
/* no mode selected, request one */
if(Mode_ID == INVALID_ID)
{
struct ScreenModeRequester *sreq = NULL;
if (!wb)
{
#ifdef STORM
if(sreq = (struct ScreenModeRequester *)AllocAslRequest(ASL_ScreenModeRequest,asltags))
#else
if(sreq = (struct ScreenModeRequester *)AllocAslRequestTags(ASL_ScreenModeRequest,TAG_END))
#endif
{
if(AslRequest(sreq,TAG_END))
{
Mode_ID = sreq -> sm_DisplayID;
printf("Next time, use option -m0x%lx\n",Mode_ID);
}
else
Error("No valid screenmode selected\n");
FreeAslRequest(sreq);
}
}
}
/* open cybergraphics.library */
if(CyberGfxBase = OpenLibrary(CYBERGFXNAME,CYBERGFXVERSION))
{
if(IsCyberModeID(Mode_ID))
displayIsNative = FALSE;
}
#ifdef STORM
if (!(ChunkyPPCBase = OpenLibrary("chunkyppc.library",0)))
{
direct=0;
}
#endif
IO_StartupTimer();
/* setup automatically closing of the display */
#ifndef STORM
if(onbreak(&__amiga_exit)) Error("onbreak failed");
#endif
if(atexit(&__amiga_checkdisplay)) Error("atexit failed");
/* open screen */
if(displayIsNative)
{
if( !(temp = (unsigned char *)AllocRaster(Coded_Picture_Width*Double_Pixels,Coded_Picture_Height*Double_Pixels*8)) )
Error("AllocRaster failed");
/* initialize bitmap */
if (!wb)
{
InitBitMap( &displayBitMap, 8, Coded_Picture_Width*Double_Pixels, Coded_Picture_Height*Double_Pixels);
/* attach image data to bitmap */
for( i=0; i<8;i++ )
displayBitMap.Planes[i] = temp + i * RASSIZE (Coded_Picture_Width*Double_Pixels, Coded_Picture_Height*Double_Pixels);
if(!(displayScreen = OpenScreenTags(NULL,
SA_BitMap,&displayBitMap,
SA_Width,Coded_Picture_Width*Double_Pixels,
SA_Height,Coded_Picture_Height*Double_Pixels,
SA_Title,"MPEG-2",
SA_DisplayID,Mode_ID,
SA_Depth,8,
SA_ShowTitle,FALSE,
TAG_END)))
Error("OpenScreenTags failed");
}
}
else
{
if (!wb)
{
if(!(displayScreen = OpenScreenTags(NULL,
SA_Width,Coded_Picture_Width*Double_Pixels,
SA_Height,Coded_Picture_Height*Double_Pixels,
SA_Title,"MPEG-2",
SA_DisplayID,Mode_ID,
SA_Depth,8,
SA_ShowTitle,FALSE,
TAG_END)))
Error("OpenScreenTags failed");
}
}
#ifdef STORM
if ((Coded_Picture_Width*Double_Pixels)%64==0) opt=0;
else if ((Coded_Picture_Width*Double_Pixels)%8==0) opt=1;
else opt=2;
#endif
/* open window */
#ifdef STORM
if (direct)
{
helpbuf[0].ti_Tag=LBMI_BASEADDRESS;
helpbuf[0].ti_Data=(ULONG)&address;
helpbuf[1].ti_Tag=LBMI_BYTESPERROW;
helpbuf[1].ti_Data=(ULONG)&bpr;
helpbuf[2].ti_Tag=TAG_END;
helpbuf[2].ti_Data=0;
UnLockBitMap(LockBitMapTagList((displayScreen->RastPort).BitMap,helpbuf));
}
#endif
if (wb)
{
direct=0;
displayIsNative=0;
if(!(displayWindow = OpenWindowTags(NULL,
WA_Title,"MPEG-2 Display",
WA_InnerWidth,Coded_Picture_Width*Double_Pixels,
WA_InnerHeight,Coded_Picture_Height*Double_Pixels,
WA_GimmeZeroZero,TRUE,
WA_DragBar,TRUE,
WA_DepthGadget,TRUE,
WA_IDCMP,IDCMP_RAWKEY,
WA_Activate,TRUE,
WA_NewLookMenus,TRUE,
TAG_END)))
Error("OpenWindowTags failed");
wbcolors=(UBYTE *)AllocVec(256*4,MEMF_FAST|MEMF_CLEAR);
if (!wbcolors)
{
Error("Not enough memory");
}
colarray1=&(transtable[0]);
WBColorTable[0] = 0x01000000;
WBColorTable[3*256+1] = 0;
GetRGB32((displayWindow->WScreen->ViewPort).ColorMap,0,256,WBColorTable+1);
}
else
{
if(!(displayWindow = OpenWindowTags(NULL,WA_CustomScreen,displayScreen,
WA_Title,"MPEG-2 Display",
WA_Width,Coded_Picture_Width*Double_Pixels,
WA_Height,Coded_Picture_Height*Double_Pixels,
WA_IDCMP,IDCMP_RAWKEY,
WA_Backdrop,TRUE,
WA_Borderless,TRUE,
WA_RMBTrap,TRUE,
WA_Activate,TRUE,
WA_NewLookMenus,TRUE,
WA_ScreenTitle,"MPEG-2",
TAG_END)))
Error("OpenWindowTags failed");
}
//displayScreen = displayWindow -> WScreen;
/* matrix coefficients */
rp=displayWindow->RPort;
SetAPen(rp,1);
crv = Inverse_Table_6_9[matrix_coefficients][0];
cbu = Inverse_Table_6_9[matrix_coefficients][1];
cgu = Inverse_Table_6_9[matrix_coefficients][2];
cgv = Inverse_Table_6_9[matrix_coefficients][3];
/* allocate colors */
/* color allocation:
* i is the (internal) 8 bit color number, it consists of separate
* bit fields for Y, U and V: i = (yyyyuuvv), we don't use yyyy=0000
* and yyyy=1111, this leaves 32 colors for other applications
*
* the allocated colors correspond to the following Y, U and V values:
* Y: 24, 40, 56, 72, 88, 104, 120, 136, 152, 168, 184, 200, 216, 232
* U,V: -48, -16, 16, 48
*
* U and V values span only about half the color space; this gives
* usually much better quality, although highly saturated colors can
* not be displayed properly
*
* translation to R,G,B is implicitly done by the color look-up table
*/
for( i=0; i<256; i++) Pixel[i] = 0xff; /* clear to make sure that all colors are correctly freed */
mycolors[0]=0x01000000;
mycolors[3*256+1]=0;
mycolors[1]=255<<24;
mycolors[2]=255<<24;
mycolors[3]=255<<24;
for (i=1;i<16;i++)
{
mycolors[3*i+1]=0;
mycolors[3*i+2]=0;
mycolors[3*i+3]=0;
}
for( i=16; i<240; i++ )
{
/* color space conversion */
Y = 16*((i>>4)&15) + 8;
Cb = 32*((i>>2)&3) - 48;
Cr = 32*(i&3) - 48;
Y = 76309 * (Y - 16); /* (255/219)*65536 */
R = Clip[(Y + crv*Cr + 32768)>>16];
G = Clip[(Y - cgu*Cb - cgv*Cr + 32768)>>16];
B = Clip[(Y + cbu*Cb + 32786)>>16];
mycolors[3*i+1]=R<<24;
mycolors[3*i+2]=G<<24;
mycolors[3*i+3]=B<<24;
//if (!wb) SetRGB32(&displayScreen -> ViewPort,i,R<<24,G<<24,B<<24);
Pixel[i] = i;
}
if (!wb) LoadRGB32(&displayScreen->ViewPort,mycolors);
else LoadRGBRtg(displayWindow,mycolors);
/* allocate temporary rastport */
if(!(tempRastPort = malloc(sizeof(struct RastPort))))
Error("malloc failed");
#if 0
memcpy(tempRastPort,&displayScreen -> RastPort,sizeof(struct RastPort));
tempRastPort -> Layer = NULL;
tempRastPort -> BitMap = NULL;
if(!(tempRastPort -> BitMap = AllocBitMap(((((Coded_Picture_Width*Double_Pixels)+15)>>4)<<1),1,((displayScreen -> RastPort).BitMap) -> Depth,NULL,NULL)))
Error("AllocBitMap failed");
#endif
/* allocate buffers */
if(!(Dithered_Image = (unsigned char *)malloc((Coded_Picture_Width)*4*(Coded_Picture_Height))))
Error("malloc failed");
if(!progressive_sequence)
{
if(!(Dithered_Image2 = (unsigned char *)malloc((Coded_Picture_Width)*4*(Coded_Picture_Height))))
Error("malloc failed");
}
if(!(Doubled_Image = (unsigned char *)malloc((Coded_Picture_Width*4*Double_Pixels)*(Coded_Picture_Height*Double_Pixels))))
Error("malloc failed");
}
extern int fpscount;
int __amiga_exit(void)
{
fprintf(stderr,"CTRL-C received\n");
return 1L;
}
void __amiga_checkdisplay(void)
{
if(displayIsOpen) Terminate_Display_Process();
}
void Terminate_Display_Process()
{
int i;
if(Doubled_Image)
{
free(Doubled_Image);
Doubled_Image = NULL;
}
if(Dithered_Image2)
{
free(Dithered_Image2);
Dithered_Image2 = NULL;
}
if(Dithered_Image)
{
free(Dithered_Image);
Dithered_Image = NULL;
}
#if 0
if(tempRastPort)
{
if(tempRastPort -> BitMap) FreeBitMap(tempRastPort -> BitMap);
free(tempRastPort);
tempRastPort = NULL;
}
#endif
if (!wb)
{
//for(i=0;i<256;i++) ReleasePen( (displayScreen -> ViewPort).ColorMap,Pixel[i]);
}
else
{
int i;
struct ColorMap *ColorMap=((displayWindow->WScreen)->ViewPort).ColorMap;
for (i=0; i<256; i++) ReleasePen(ColorMap,transtable[i]);
LoadRGB32(&(displayWindow->WScreen->ViewPort),WBColorTable);
FreeVec(wbcolors);
}
if(displayWindow) CloseWindow(displayWindow);
if(displayScreen&&(!wb)) CloseScreen(displayScreen);
if (!wb)
{
if(displayBitMap.Planes[0])
{
FreeRaster(displayBitMap.Planes[0],Coded_Picture_Width*Double_Pixels,Coded_Picture_Height*Double_Pixels*8);
displayBitMap.Planes[0]=NULL;
}
}
displayIsOpen = FALSE;
/* close cybergraphics.library */
if(CyberGfxBase)
{
CloseLibrary(CyberGfxBase);
CyberGfxBase = NULL;
}
#ifdef STORM
if (ChunkyPPCBase)
{
CloseLibrary(ChunkyPPCBase);
ChunkyPPCBase=NULL;
}
#endif
IO_ShutdownTimer();
if (fpscount) printf("Average fps rate: %f\n",(float)(((float)frames)/((float)secs)));
}
int Frame_Count = NULL;
extern int fpscount;
int truecolor=1;
void ARGBtoBGR(unsigned char *address,unsigned char *Dithered_Image,int w,int h,int bpr);
UBYTE *taste=(UBYTE *)0xbfec01;
#ifdef STORM
void ConvertFrame(UBYTE *,UBYTE *,unsigned long);
static void Display_Image(void *Ximage_Ptr,unsigned char *Dithered_Image)
#else
static void Display_Image(Ximage_Ptr,Dithered_Image)
void *Ximage_Ptr;
unsigned char *Dithered_Image;
#endif
{
//static int count=0;
//printf("display: %ld\r",count++);
//fflush(stdout);
/* scale picture to the double if -h is present */
if (*taste==0x39)
{
Terminate_Display_Process();
exit(0);
}
if(Double_Pixels == 2)
{
int i,j;
unsigned char *dest_pointer = Doubled_Image;
unsigned char *source_pointer = Dithered_Image;
for(i=0;i<Coded_Picture_Height;i++)
{
for(j=0;j<Coded_Picture_Width;j++)
{
*(dest_pointer++)=*source_pointer;
*(dest_pointer++)=*(source_pointer++);
}
source_pointer-=Coded_Picture_Width;
for(j=0;j<Coded_Picture_Width;j++)
{
*(dest_pointer)++=*source_pointer;
*(dest_pointer)++=*(source_pointer++);
}
}
Dithered_Image = Doubled_Image;
}
if (!wb)
{
#ifdef STORM
if (direct)
{
if (!displayIsNative)
{
if (opt==0) ChunkyNoffFastest(address,Dithered_Image,(Coded_Picture_Width*Double_Pixels),(Coded_Picture_Height*Double_Pixels),bpr);
else if (opt==1) ChunkyNoffFast(address,Dithered_Image,(Coded_Picture_Width*Double_Pixels),(Coded_Picture_Height*Double_Pixels),bpr);
else ChunkyNoffNormal(address,Dithered_Image,(Coded_Picture_Width*Double_Pixels),(Coded_Picture_Height*Double_Pixels),bpr);
}
else c2p1x1_8_c5_ppc(Dithered_Image,displayBitMap.Planes[0],
Coded_Picture_Width*Double_Pixels,Coded_Picture_Height*Double_Pixels,
0, 0,
((Coded_Picture_Width*Double_Pixels)*(Coded_Picture_Height*Double_Pixels))/8);
}
else
#endif
{
if (!truecolor)
{
if(displayIsNative)
c2p1x1_8_c5_ppc(Dithered_Image,displayBitMap.Planes[0],
Coded_Picture_Width*Double_Pixels,Coded_Picture_Height*Double_Pixels,
0, 0,
((Coded_Picture_Width*Double_Pixels)*(Coded_Picture_Height*Double_Pixels))/8);
else
WritePixelArray8(&displayScreen -> RastPort,0,0,(Coded_Picture_Width*Double_Pixels)-1,(Coded_Picture_Height*Double_Pixels)-1,Dithered_Image,&displayScreen -> RastPort);
}
else
{
WritePixelArray(Dithered_Image,0,0,4*Coded_Picture_Width*Double_Pixels,rp,0,0,Coded_Picture_Width*Double_Pixels,Coded_Picture_Height*Double_Pixels,RECTFMT_ARGB);
}
}
}
else
{
if (!truecolor)
{
ConvertFrame(Dithered_Image,transtable,Coded_Picture_Width*Double_Pixels*Coded_Picture_Height*Double_Pixels);
WritePixelArray8(rp,0,0,(Coded_Picture_Width*Double_Pixels)-1,(Coded_Picture_Height*Double_Pixels)-1,Dithered_Image,rp);
}
else
{
WritePixelArray(Dithered_Image,0,0,4*Coded_Picture_Width*Double_Pixels,rp,0,0,Coded_Picture_Width*Double_Pixels,Coded_Picture_Height*Double_Pixels,RECTFMT_ARGB);
}
}
if (fpscount) video_do_fps();
}
void Display_Second_Field()
{
if(Frame_Count)
{
Frame_Count--;
return;
}
else
Frame_Count = Frame_Skip;
Display_Image(Ximage_Ptr2,Dithered_Image2);
}
/* 4x4 ordered dither
*
* threshold pattern:
* 0 8 2 10
* 12 4 14 6
* 3 11 1 9
* 15 7 13 5
*/
void Initialize_Dither_Matrix()
{
int i, v;
for (i=-8; i<256+8; i++)
{
v = i>>4;
if (v<1)
v = 1;
else if (v>14)
v = 14;
Y_Table[i+8] = v<<4;
}
for (i=0; i<128+16; i++)
{
v = (i-40)>>4;
if (v<0)
v = 0;
else if (v>3)
v = 3;
Cb_Table[i] = v<<2;
Cr_Table[i] = v;
}
}
static void conv422to444(unsigned char *src,unsigned char *dst)
{
int i, i2, w, j, im3, im2, im1, ip1, ip2, ip3;
w = Coded_Picture_Width>>1;
if (base.MPEG2_Flag)
{
for (j=0; j<Coded_Picture_Height; j++)
{
for (i=0; i<w; i++)
{
i2 = i<<1;
im2 = (i<2) ? 0 : i-2;
im1 = (i<1) ? 0 : i-1;
ip1 = (i<w-1) ? i+1 : w-1;
ip2 = (i<w-2) ? i+2 : w-1;
ip3 = (i<w-3) ? i+3 : w-1;
/* FIR filter coefficients (*256): 21 0 -52 0 159 256 159 0 -52 0 21 */
/* even samples (0 0 256 0 0) */
dst[i2] = src[i];
/* odd samples (21 -52 159 159 -52 21) */
dst[i2+1] = Clip[(int)(21*(src[im2]+src[ip3])
-52*(src[im1]+src[ip2])
+159*(src[i]+src[ip1])+128)>>8];
}
src+= w;
dst+= Coded_Picture_Width;
}
}
else
{
for (j=0; j<Coded_Picture_Height; j++)
{
for (i=0; i<w; i++)
{
i2 = i<<1;
im3 = (i<3) ? 0 : i-3;
im2 = (i<2) ? 0 : i-2;
im1 = (i<1) ? 0 : i-1;
ip1 = (i<w-1) ? i+1 : w-1;
ip2 = (i<w-2) ? i+2 : w-1;
ip3 = (i<w-3) ? i+3 : w-1;
/* FIR filter coefficients (*256): 5 -21 70 228 -37 11 */
dst[i2] = Clip[(int)( 5*src[im3]
-21*src[im2]
+70*src[im1]
+228*src[i]
-37*src[ip1]
+11*src[ip2]+128)>>8];
dst[i2+1] = Clip[(int)( 5*src[ip3]
-21*src[ip2]
+70*src[ip1]
+228*src[i]
-37*src[im1]
+11*src[im2]+128)>>8];
}
src+= w;
dst+= Coded_Picture_Width;
}
}
}
/* vertical 1:2 interpolation filter */
static void conv420to422(unsigned char *src,unsigned char *dst)
{
int w, h, i, j, j2;
int jm6, jm5, jm4, jm3, jm2, jm1, jp1, jp2, jp3, jp4, jp5, jp6, jp7;
w = Coded_Picture_Width>>1;
h = Coded_Picture_Height>>1;
if (progressive_frame)
{
/* intra frame */
for (i=0; i<w; i++)
{
for (j=0; j<h; j++)
{
j2 = j<<1;
jm3 = (j<3) ? 0 : j-3;
jm2 = (j<2) ? 0 : j-2;
jm1 = (j<1) ? 0 : j-1;
jp1 = (j<h-1) ? j+1 : h-1;
jp2 = (j<h-2) ? j+2 : h-1;
jp3 = (j<h-3) ? j+3 : h-1;
/* FIR filter coefficients (*256): 5 -21 70 228 -37 11 */
/* New FIR filter coefficients (*256): 3 -16 67 227 -32 7 */
dst[w*j2] = Clip[(int)( 3*src[w*jm3]
-16*src[w*jm2]
+67*src[w*jm1]
+227*src[w*j]
-32*src[w*jp1]
+7*src[w*jp2]+128)>>8];
dst[w*(j2+1)] = Clip[(int)( 3*src[w*jp3]
-16*src[w*jp2]
+67*src[w*jp1]
+227*src[w*j]
-32*src[w*jm1]
+7*src[w*jm2]+128)>>8];
}
src++;
dst++;
}
}
else
{
/* intra field */
for (i=0; i<w; i++)
{
for (j=0; j<h; j+=2)
{
j2 = j<<1;
/* top field */
jm6 = (j<6) ? 0 : j-6;
jm4 = (j<4) ? 0 : j-4;
jm2 = (j<2) ? 0 : j-2;
jp2 = (j<h-2) ? j+2 : h-2;
jp4 = (j<h-4) ? j+4 : h-2;
jp6 = (j<h-6) ? j+6 : h-2;
/* Polyphase FIR filter coefficients (*256): 2 -10 35 242 -18 5 */
/* New polyphase FIR filter coefficients (*256): 1 -7 30 248 -21 5 */
dst[w*j2] = Clip[(int)( 1*src[w*jm6]
-7*src[w*jm4]
+30*src[w*jm2]
+248*src[w*j]
-21*src[w*jp2]
+5*src[w*jp4]+128)>>8];
/* Polyphase FIR filter coefficients (*256): 11 -38 192 113 -30 8 */
/* New polyphase FIR filter coefficients (*256):7 -35 194 110 -24 4 */
dst[w*(j2+2)] = Clip[(int)( 7*src[w*jm4]
-35*src[w*jm2]
+194*src[w*j]
+110*src[w*jp2]
-24*src[w*jp4]
+4*src[w*jp6]+128)>>8];
/* bottom field */
jm5 = (j<5) ? 1 : j-5;
jm3 = (j<3) ? 1 : j-3;
jm1 = (j<1) ? 1 : j-1;
jp1 = (j<h-1) ? j+1 : h-1;
jp3 = (j<h-3) ? j+3 : h-1;
jp5 = (j<h-5) ? j+5 : h-1;
jp7 = (j<h-7) ? j+7 : h-1;
/* Polyphase FIR filter coefficients (*256): 11 -38 192 113 -30 8 */
/* New polyphase FIR filter coefficients (*256):7 -35 194 110 -24 4 */
dst[w*(j2+1)] = Clip[(int)( 7*src[w*jp5]
-35*src[w*jp3]
+194*src[w*jp1]
+110*src[w*jm1]
-24*src[w*jm3]
+4*src[w*jm5]+128)>>8];
dst[w*(j2+3)] = Clip[(int)( 1*src[w*jp7]
-7*src[w*jp5]
+30*src[w*jp3]
+248*src[w*jp1]
-21*src[w*jm1]
+5*src[w*jm3]+128)>>8];
}
src++;
dst++;
}
}
}
/* Convert YUV->RGB *without* using interpolation */
static void yuv_to_rgb_noint(unsigned char *src[],unsigned char *dst)
{
int i,j;
int y,u,v;
int crv, cbu, cgu, cgv;
unsigned char *py,*pu,*pv;
unsigned char r, g, b, xdiffy, xdiffuv;
py = src[0];
pu = src[1];
pv = src[2];
/* matrix coefficients */
crv = Inverse_Table_6_9[matrix_coefficients][0];
cbu = Inverse_Table_6_9[matrix_coefficients][1];
cgu = Inverse_Table_6_9[matrix_coefficients][2];
cgv = Inverse_Table_6_9[matrix_coefficients][3];
xdiffuv = xdiffy = Coded_Picture_Width-horizontal_size;
if (chroma_format!=CHROMA444)
xdiffuv/=2;
for (j=0; j<vertical_size; j++)
{
for (i=0; i<horizontal_size; i++)
{
if (i%2==0)
{
u = *pu++ - 128;
v = *pv++ - 128;
}
else if (chroma_format==CHROMA444)
{
u = *pu++ - 128;
v = *pv++ - 128;
}
y = 76309 * (*py++ - 16); /* (255/219)*65536 */
r = Clip[(y + crv*v + 32768)>>16];
g = Clip[(y - cgu*u - cgv*v + 32768)>>16];
b = Clip[(y + cbu*u + 32786)>>16];
*dst++ = r;
*dst++ = g;
*dst++ = b;
*dst++ = b;
}
/* Increase pointers */
py+=xdiffy;
pu+=xdiffuv;
pv+=xdiffuv;
if (chroma_format==CHROMA420 && j%2==0)
{
pu -= Chroma_Width;
pv -= Chroma_Width;
}
}
}
/* Convert YUV->RGB using interpolation */
static void yuv_to_rgb_int(unsigned char *src[],unsigned char *dst)
{
int i, j;
int y, u, v;
int crv, cbu, cgu, cgv;
int height, incr;
unsigned char *py, *pu, *pv;
unsigned char r, g, b;
static unsigned char *u422, *v422, *u444, *v444;
/* Init */
height=vertical_size;
incr=Coded_Picture_Width;
/* Perform conversion */
if (chroma_format==CHROMA444)
{
u444 = src[1];
v444 = src[2];
}
else
{
if (!u444)
{
if (chroma_format==CHROMA420)
{
if (!(u422 = (unsigned char *)malloc((Coded_Picture_Width>>1)
*Coded_Picture_Height)))
Error("malloc failed");
if (!(v422 = (unsigned char *)malloc((Coded_Picture_Width>>1)
*Coded_Picture_Height)))
Error("malloc failed");
}
if (!(u444 = (unsigned char *)malloc(Coded_Picture_Width
*Coded_Picture_Height)))
Error("malloc failed");
if (!(v444 = (unsigned char *)malloc(Coded_Picture_Width
*Coded_Picture_Height)))
Error("malloc failed");
}
if (chroma_format==CHROMA420)
{
conv420to422(src[1],u422);
conv420to422(src[2],v422);
conv422to444(u422,u444);
conv422to444(v422,v444);
}
else
{
conv422to444(src[1],u444);
conv422to444(src[2],v444);
}
}
/* matrix coefficients */
crv = Inverse_Table_6_9[matrix_coefficients][0];
cbu = Inverse_Table_6_9[matrix_coefficients][1];
cgu = Inverse_Table_6_9[matrix_coefficients][2];
cgv = Inverse_Table_6_9[matrix_coefficients][3];
for (i=0; i<height; i++)
{
py = src[0] + incr*i;
pu = u444 + incr*i;
pv = v444 + incr*i;
for (j=0; j<horizontal_size; j++)
{
u = *pu++ - 128;
v = *pv++ - 128;
y = 76309 * (*py++ - 16); /* (255/219)*65536 */
r = Clip[(y + crv*v + 32768)>>16];
g = Clip[(y - cgu*u - cgv*v + 32768)>>16];
b = Clip[(y + cbu*u + 32786)>>16];
*dst++ = r;
*dst++ = g;
*dst++ = b;
*dst++ = b;
}
}
}
static void yuv_to_rgb(unsigned char *src[],unsigned char *dst)
{
#ifdef BLA
yuv_to_rgb_int(src,dst);
#else
yuv_to_rgb_noint(src,dst);
#endif
}
static void Dither_Frame_TrueCol(unsigned char *src[])
{
if (!displayIsNative)
{
/* Perform YUV->RGB directly to destination */
yuv_to_rgb(src, Dithered_Image);
}
else
{
/* YUV->RGB */
//yuv_to_rgb(src, RGB_Image);
/* RGB -> HAM6/8 conversion */
//ham_c2p(RGB_Image, Dithered_Image, horizontal_size, vertical_size);
// Fix this still...
}
}
#ifdef STORM
void dither(unsigned char *src[])
#else
void dither(src)
unsigned char *src[];
#endif
{
/* should this test only the display flag, not progressive_sequence ? --CF */
/* CHANGE 95/05/13: progressive_sequence -> progressive_frame */
if(Frame_Count)
{
Frame_Count--;
return;
}
else
Frame_Count = Frame_Skip;
if (truecolor==0)
{
if( progressive_frame || Display_Progressive_Flag)
Dither_Frame(src);
else
{
if ((picture_structure==FRAME_PICTURE && top_field_first) || picture_structure==BOTTOM_FIELD)
{
/* top field first */
if (chroma_format==CHROMA420 && hiQdither)
{
Dither_Top_Field420(src,Dithered_Image);
Dither_Bottom_Field420(src,Dithered_Image2);
}
else
{
Dither_Top_Field(src,Dithered_Image);
Dither_Bottom_Field(src,Dithered_Image2);
}
}
else
{
/* bottom field first */
if (chroma_format==CHROMA420 && hiQdither)
{
Dither_Bottom_Field420(src,Dithered_Image);
Dither_Top_Field420(src,Dithered_Image2);
}
else
{
Dither_Bottom_Field(src,Dithered_Image);
Dither_Top_Field(src,Dithered_Image2);
}
}
}
}
else
{
Dither_Frame_TrueCol(src);
}
Display_Image(Ximage_Ptr,Dithered_Image);
}
#ifdef STORM
static void Dither_Frame(unsigned char *src[])
#else
static void Dither_Frame(src)
unsigned char *src[];
#endif
{
int i,j;
int y,u,v;
unsigned char *py,*pu,*pv,*dst;
py = src[0];
pu = src[1];
pv = src[2];
dst = Dithered_Image;
for (j=0; j<Coded_Picture_Height; j+=4)
{
/* line j + 0 */
for (i=0; i<Coded_Picture_Width; i+=4)
{
y = *py++;
u = *pu++ >> 1;
v = *pv++ >> 1;
*dst++ = Pixel[Y_Table[y]|Cb_Table[u]|Cr_Table[v]];
y = *py++;
if (chroma_format==CHROMA444)
{
u = *pu++ >> 1;
v = *pv++ >> 1;
}
*dst++ = Pixel[Y_Table[y+8]|Cb_Table[u+8]|Cr_Table[v+8]];
y = *py++;
u = *pu++ >> 1;
v = *pv++ >> 1;
*dst++ = Pixel[Y_Table[y+2]|Cb_Table[u+2]|Cr_Table[v+2]];
y = *py++;
if (chroma_format==CHROMA444)
{
u = *pu++ >> 1;
v = *pv++ >> 1;
}
*dst++ = Pixel[Y_Table[y+10]|Cb_Table[u+10]|Cr_Table[v+10]];
}
if (chroma_format==CHROMA420)
{
pu -= Chroma_Width;
pv -= Chroma_Width;
}
/* line j + 1 */
for (i=0; i<Coded_Picture_Width; i+=4)
{
y = *py++;
u = *pu++ >> 1;
v = *pv++ >> 1;
*dst++ = Pixel[Y_Table[y+12]|Cb_Table[u+12]|Cr_Table[v+12]];
y = *py++;
if (chroma_format==CHROMA444)
{
u = *pu++ >> 1;
v = *pv++ >> 1;
}
*dst++ = Pixel[Y_Table[y+4]|Cb_Table[u+4]|Cr_Table[v+4]];
y = *py++;
u = *pu++ >> 1;
v = *pv++ >> 1;
*dst++ = Pixel[Y_Table[y+14]|Cb_Table[u+14]|Cr_Table[v+14]];
y = *py++;
if (chroma_format==CHROMA444)
{
u = *pu++ >> 1;
v = *pv++ >> 1;
}
*dst++ = Pixel[Y_Table[y+6]|Cb_Table[u+6]|Cr_Table[v+6]];
}
/* line j + 2 */
for (i=0; i<Coded_Picture_Width; i+=4)
{
y = *py++;
u = *pu++ >> 1;
v = *pv++ >> 1;
*dst++ = Pixel[Y_Table[y+3]|Cb_Table[u+3]|Cr_Table[v+3]];
y = *py++;
if (chroma_format==CHROMA444)
{
u = *pu++ >> 1;
v = *pv++ >> 1;
}
*dst++ = Pixel[Y_Table[y+11]|Cb_Table[u+11]|Cr_Table[v+11]];
y = *py++;
u = *pu++ >> 1;
v = *pv++ >> 1;
*dst++ = Pixel[Y_Table[y+1]|Cb_Table[u+1]|Cr_Table[v+1]];
y = *py++;
if (chroma_format==CHROMA444)
{
u = *pu++ >> 1;
v = *pv++ >> 1;
}
*dst++ = Pixel[Y_Table[y+9]|Cb_Table[u+9]|Cr_Table[v+9]];
}
if (chroma_format==CHROMA420)
{
pu -= Chroma_Width;
pv -= Chroma_Width;
}
/* line j + 3 */
for (i=0; i<Coded_Picture_Width; i+=4)
{
y = *py++;
u = *pu++ >> 1;
v = *pv++ >> 1;
*dst++ = Pixel[Y_Table[y+15]|Cb_Table[u+15]|Cr_Table[v+15]];
y = *py++;
if (chroma_format==CHROMA444)
{
u = *pu++ >> 1;
v = *pv++ >> 1;
}
*dst++ = Pixel[Y_Table[y+7]|Cb_Table[u+7]|Cr_Table[v+7]];
y = *py++;
u = *pu++ >> 1;
v = *pv++ >> 1;
*dst++ = Pixel[Y_Table[y+13]|Cb_Table[u+13]|Cr_Table[v+13]];
y = *py++;
if (chroma_format==CHROMA444)
{
u = *pu++ >> 1;
v = *pv++ >> 1;
}
*dst++ = Pixel[Y_Table[y+5]|Cb_Table[u+5]|Cr_Table[v+5]];
}
}
}
#ifdef STORM
static void Dither_Top_Field(unsigned char *src[], unsigned char *dst)
#else
static void Dither_Top_Field(src,dst)
unsigned char *src[];
unsigned char *dst;
#endif
{
int i,j;
int y,Y2,u,v;
unsigned char *py,*Y2_ptr,*pu,*pv,*dst2;
py = src[0];
Y2_ptr = src[0] + (Coded_Picture_Width<<1);
pu = src[1];
pv = src[2];
dst2 = dst + Coded_Picture_Width;
for (j=0; j<Coded_Picture_Height; j+=4)
{
/* line j + 0, j + 1 */
for (i=0; i<Coded_Picture_Width; i+=4)
{
y = *py++;
Y2 = *Y2_ptr++;
u = *pu++ >> 1;
v = *pv++ >> 1;
*dst++ = Pixel[Y_Table[y]|Cb_Table[u]|Cr_Table[v]];
*dst2++ = Pixel[Y_Table[((y+Y2)>>1)+12]|Cb_Table[u+12]|Cr_Table[v+12]];
y = *py++;
Y2 = *Y2_ptr++;
if (chroma_format==CHROMA444)
{
u = *pu++ >> 1;
v = *pv++ >> 1;
}
*dst++ = Pixel[Y_Table[y+8]|Cb_Table[u+8]|Cr_Table[v+8]];
*dst2++ = Pixel[Y_Table[((y+Y2)>>1)+4]|Cb_Table[u+4]|Cr_Table[v+4]];
y = *py++;
Y2 = *Y2_ptr++;
u = *pu++ >> 1;
v = *pv++ >> 1;
*dst++ = Pixel[Y_Table[y+2]|Cb_Table[u+2]|Cr_Table[v+2]];
*dst2++ = Pixel[Y_Table[((y+Y2)>>1)+14]|Cb_Table[u+14]|Cr_Table[v+14]];
y = *py++;
Y2 = *Y2_ptr++;
if (chroma_format==CHROMA444)
{
u = *pu++ >> 1;
v = *pv++ >> 1;
}
*dst++ = Pixel[Y_Table[y+10]|Cb_Table[u+10]|Cr_Table[v+10]];
*dst2++ = Pixel[Y_Table[((y+Y2)>>1)+6]|Cb_Table[u+6]|Cr_Table[v+6]];
}
py += Coded_Picture_Width;
if (j!=(Coded_Picture_Height-4))
Y2_ptr += Coded_Picture_Width;
else
Y2_ptr -= Coded_Picture_Width;
dst += Coded_Picture_Width;
dst2 += Coded_Picture_Width;
if (chroma_format==CHROMA420)
{
pu -= Chroma_Width;
pv -= Chroma_Width;
}
else
{
pu += Chroma_Width;
pv += Chroma_Width;
}
/* line j + 2, j + 3 */
for (i=0; i<Coded_Picture_Width; i+=4)
{
y = *py++;
Y2 = *Y2_ptr++;
u = *pu++ >> 1;
v = *pv++ >> 1;
*dst++ = Pixel[Y_Table[y+3]|Cb_Table[u+3]|Cr_Table[v+3]];
*dst2++ = Pixel[Y_Table[((y+Y2)>>1)+15]|Cb_Table[u+15]|Cr_Table[v+15]];
y = *py++;
Y2 = *Y2_ptr++;
if (chroma_format==CHROMA444)
{
u = *pu++ >> 1;
v = *pv++ >> 1;
}
*dst++ = Pixel[Y_Table[y+11]|Cb_Table[u+11]|Cr_Table[v+11]];
*dst2++ = Pixel[Y_Table[((y+Y2)>>1)+7]|Cb_Table[u+7]|Cr_Table[v+7]];
y = *py++;
Y2 = *Y2_ptr++;
u = *pu++ >> 1;
v = *pv++ >> 1;
*dst++ = Pixel[Y_Table[y+1]|Cb_Table[u+1]|Cr_Table[v+1]];
*dst2++ = Pixel[Y_Table[((y+Y2)>>1)+13]|Cb_Table[u+13]|Cr_Table[v+13]];
y = *py++;
Y2 = *Y2_ptr++;
if (chroma_format==CHROMA444)
{
u = *pu++ >> 1;
v = *pv++ >> 1;
}
*dst++ = Pixel[Y_Table[y+9]|Cb_Table[u+9]|Cr_Table[v+9]];
*dst2++ = Pixel[Y_Table[((y+Y2)>>1)+5]|Cb_Table[u+5]|Cr_Table[v+5]];
}
py += Coded_Picture_Width;
Y2_ptr += Coded_Picture_Width;
dst += Coded_Picture_Width;
dst2 += Coded_Picture_Width;
pu += Chroma_Width;
pv += Chroma_Width;
}
}
#ifdef STORM
static void Dither_Bottom_Field(unsigned char *src[], unsigned char *dst)
#else
static void Dither_Bottom_Field(src,dst)
unsigned char *src[];
unsigned char *dst;
#endif
{
int i,j;
int y,Y2,u,v;
unsigned char *py,*Y2_ptr,*pu,*pv,*dst2;
py = src[0] + Coded_Picture_Width;
Y2_ptr = py;
pu = src[1] + Chroma_Width;
pv = src[2] + Chroma_Width;
dst2 = dst + Coded_Picture_Width;
for (j=0; j<Coded_Picture_Height; j+=4)
{
/* line j + 0, j + 1 */
for (i=0; i<Coded_Picture_Width; i+=4)
{
y = *py++;
Y2 = *Y2_ptr++;
u = *pu++ >> 1;
v = *pv++ >> 1;
*dst++ = Pixel[Y_Table[((y+Y2)>>1)]|Cb_Table[u]|Cr_Table[v]];
*dst2++ = Pixel[Y_Table[Y2+12]|Cb_Table[u+12]|Cr_Table[v+12]];
y = *py++;
Y2 = *Y2_ptr++;
if (chroma_format==CHROMA444)
{
u = *pu++ >> 1;
v = *pv++ >> 1;
}
*dst++ = Pixel[Y_Table[((y+Y2)>>1)+8]|Cb_Table[u+8]|Cr_Table[v+8]];
*dst2++ = Pixel[Y_Table[Y2+4]|Cb_Table[u+4]|Cr_Table[v+4]];
y = *py++;
Y2 = *Y2_ptr++;
u = *pu++ >> 1;
v = *pv++ >> 1;
*dst++ = Pixel[Y_Table[((y+Y2)>>1)+2]|Cb_Table[u+2]|Cr_Table[v+2]];
*dst2++ = Pixel[Y_Table[Y2+14]|Cb_Table[u+14]|Cr_Table[v+14]];
y = *py++;
Y2 = *Y2_ptr++;
if (chroma_format==CHROMA444)
{
u = *pu++ >> 1;
v = *pv++ >> 1;
}
*dst++ = Pixel[Y_Table[((y+Y2)>>1)+10]|Cb_Table[u+10]|Cr_Table[v+10]];
*dst2++ = Pixel[Y_Table[Y2+6]|Cb_Table[u+6]|Cr_Table[v+6]];
}
if (j==0)
py -= Coded_Picture_Width;
else
py += Coded_Picture_Width;
Y2_ptr += Coded_Picture_Width;
dst += Coded_Picture_Width;
dst2 += Coded_Picture_Width;
if (chroma_format==CHROMA420)
{
pu -= Chroma_Width;
pv -= Chroma_Width;
}
else
{
pu += Chroma_Width;
pv += Chroma_Width;
}
/* line j + 2. j + 3 */
for (i=0; i<Coded_Picture_Width; i+=4)
{
y = *py++;
Y2 = *Y2_ptr++;
u = *pu++ >> 1;
v = *pv++ >> 1;
*dst++ = Pixel[Y_Table[((y+Y2)>>1)+3]|Cb_Table[u+3]|Cr_Table[v+3]];
*dst2++ = Pixel[Y_Table[Y2+15]|Cb_Table[u+15]|Cr_Table[v+15]];
y = *py++;
Y2 = *Y2_ptr++;
if (chroma_format==CHROMA444)
{
u = *pu++ >> 1;
v = *pv++ >> 1;
}
*dst++ = Pixel[Y_Table[((y+Y2)>>1)+11]|Cb_Table[u+11]|Cr_Table[v+11]];
*dst2++ = Pixel[Y_Table[Y2+7]|Cb_Table[u+7]|Cr_Table[v+7]];
y = *py++;
Y2 = *Y2_ptr++;
u = *pu++ >> 1;
v = *pv++ >> 1;
*dst++ = Pixel[Y_Table[((y+Y2)>>1)+1]|Cb_Table[u+1]|Cr_Table[v+1]];
*dst2++ = Pixel[Y_Table[Y2+13]|Cb_Table[u+13]|Cr_Table[v+13]];
y = *py++;
Y2 = *Y2_ptr++;
if (chroma_format==CHROMA444)
{
u = *pu++ >> 1;
v = *pv++ >> 1;
}
*dst++ = Pixel[Y_Table[((y+Y2)>>1)+9]|Cb_Table[u+9]|Cr_Table[v+9]];
*dst2++ = Pixel[Y_Table[Y2+5]|Cb_Table[u+5]|Cr_Table[v+5]];
}
py += Coded_Picture_Width;
Y2_ptr += Coded_Picture_Width;
dst += Coded_Picture_Width;
dst2 += Coded_Picture_Width;
pu += Chroma_Width;
pv += Chroma_Width;
}
}
#ifndef STORM
static void Dither_Top_Field420(src,dst)
unsigned char *src[];
unsigned char *dst;
#else
static void Dither_Top_Field420(unsigned char *src[],unsigned char *dst)
#endif
{
int i,j;
int Y1,Cb1,Cr1,Y2,Cb2,Cr2;
unsigned char *Y1_ptr,*Cb1_ptr,*Cr1_ptr,*Y2_ptr,*Cb2_ptr,*Cr2_ptr,*dst2;
Y1_ptr = src[0];
Cb1_ptr = src[1];
Cr1_ptr = src[2];
Y2_ptr = Y1_ptr + (Coded_Picture_Width<<1);
Cb2_ptr = Cb1_ptr + (Chroma_Width<<1);
Cr2_ptr = Cr1_ptr + (Chroma_Width<<1);
dst2 = dst + Coded_Picture_Width;
for (j=0; j<Coded_Picture_Height; j+=4)
{
/* line j + 0, j + 1 */
for (i=0; i<Coded_Picture_Width; i+=4)
{
Y1 = *Y1_ptr++;
Y2 = *Y2_ptr++;
Cb1 = *Cb1_ptr++ >> 1;
Cr1 = *Cr1_ptr++ >> 1;
Cb2 = *Cb2_ptr++ >> 1;
Cr2 = *Cr2_ptr++ >> 1;
*dst++ = Pixel[Y_Table[((3*Y1+Y2)>>2)]|Cb_Table[Cb1]|Cr_Table[Cr1]];
*dst2++ = Pixel[Y_Table[((Y1+3*Y2)>>2)+12]|Cb_Table[((3*Cb1+Cb2)>>2)+12]
|Cr_Table[((3*Cr1+Cr2)>>2)+12]];
Y1 = *Y1_ptr++;
Y2 = *Y2_ptr++;
*dst++ = Pixel[Y_Table[((3*Y1+Y2)>>2)+8]|Cb_Table[Cb1+8]|Cr_Table[Cr1+8]];
*dst2++ = Pixel[Y_Table[((Y1+3*Y2)>>2)+4]|Cb_Table[((3*Cb1+Cb2)>>2)+4]
|Cr_Table[((3*Cr1+Cr2)>>2)+4]];
Y1 = *Y1_ptr++;
Y2 = *Y2_ptr++;
Cb1 = *Cb1_ptr++ >> 1;
Cr1 = *Cr1_ptr++ >> 1;
Cb2 = *Cb2_ptr++ >> 1;
Cr2 = *Cr2_ptr++ >> 1;
*dst++ = Pixel[Y_Table[((3*Y1+Y2)>>2)+2]|Cb_Table[Cb1+2]|Cr_Table[Cr1+2]];
*dst2++ = Pixel[Y_Table[((Y1+3*Y2)>>2)+14]|Cb_Table[((3*Cb1+Cb2)>>2)+14]
|Cr_Table[((3*Cr1+Cr2)>>2)+14]];
Y1 = *Y1_ptr++;
Y2 = *Y2_ptr++;
*dst++ = Pixel[Y_Table[((3*Y1+Y2)>>2)+10]|Cb_Table[Cb1+10]|Cr_Table[Cr1+10]];
*dst2++ = Pixel[Y_Table[((Y1+3*Y2)>>2)+6]|Cb_Table[((3*Cb1+Cb2)>>2)+6]
|Cr_Table[((3*Cr1+Cr2)>>2)+6]];
}
Y1_ptr += Coded_Picture_Width;
if (j!=(Coded_Picture_Height-4))
Y2_ptr += Coded_Picture_Width;
else
Y2_ptr -= Coded_Picture_Width;
Cb1_ptr -= Chroma_Width;
Cr1_ptr -= Chroma_Width;
Cb2_ptr -= Chroma_Width;
Cr2_ptr -= Chroma_Width;
dst += Coded_Picture_Width;
dst2 += Coded_Picture_Width;
/* line j + 2, j + 3 */
for (i=0; i<Coded_Picture_Width; i+=4)
{
Y1 = *Y1_ptr++;
Y2 = *Y2_ptr++;
Cb1 = *Cb1_ptr++ >> 1;
Cr1 = *Cr1_ptr++ >> 1;
Cb2 = *Cb2_ptr++ >> 1;
Cr2 = *Cr2_ptr++ >> 1;
*dst++ = Pixel[Y_Table[((3*Y1+Y2)>>2)+3]|Cb_Table[((Cb1+Cb2)>>1)+3]
|Cr_Table[((Cr1+Cr2)>>1)+3]];
*dst2++ = Pixel[Y_Table[((Y1+3*Y2)>>2)+15]|Cb_Table[((Cb1+3*Cb2)>>2)+15]
|Cr_Table[((Cr1+3*Cr2)>>2)+15]];
Y1 = *Y1_ptr++;
Y2 = *Y2_ptr++;
*dst++ = Pixel[Y_Table[((3*Y1+Y2)>>2)+11]|Cb_Table[((Cb1+Cb2)>>1)+11]
|Cr_Table[((Cr1+Cr2)>>1)+11]];
*dst2++ = Pixel[Y_Table[((Y1+3*Y2)>>2)+7]|Cb_Table[((Cb1+3*Cb2)>>2)+7]
|Cr_Table[((Cr1+3*Cr2)>>2)+7]];
Y1 = *Y1_ptr++;
Y2 = *Y2_ptr++;
Cb1 = *Cb1_ptr++ >> 1;
Cr1 = *Cr1_ptr++ >> 1;
Cb2 = *Cb2_ptr++ >> 1;
Cr2 = *Cr2_ptr++ >> 1;
*dst++ = Pixel[Y_Table[((3*Y1+Y2)>>2)+1]|Cb_Table[((Cb1+Cb2)>>1)+1]
|Cr_Table[((Cr1+Cr2)>>1)+1]];
*dst2++ = Pixel[Y_Table[((Y1+3*Y2)>>2)+13]|Cb_Table[((Cb1+3*Cb2)>>2)+13]
|Cr_Table[((Cr1+3*Cr2)>>2)+13]];
Y1 = *Y1_ptr++;
Y2 = *Y2_ptr++;
*dst++ = Pixel[Y_Table[((3*Y1+Y2)>>2)+9]|Cb_Table[((Cb1+Cb2)>>1)+9]
|Cr_Table[((Cr1+Cr2)>>1)+9]];
*dst2++ = Pixel[Y_Table[((Y1+3*Y2)>>2)+5]|Cb_Table[((Cb1+3*Cb2)>>2)+5]
|Cr_Table[((Cr1+3*Cr2)>>2)+5]];
}
Y1_ptr += Coded_Picture_Width;
Y2_ptr += Coded_Picture_Width;
Cb1_ptr += Chroma_Width;
Cr1_ptr += Chroma_Width;
if (j!=(Coded_Picture_Height-8))
{
Cb2_ptr += Chroma_Width;
Cr2_ptr += Chroma_Width;
}
else
{
Cb2_ptr -= Chroma_Width;
Cr2_ptr -= Chroma_Width;
}
dst += Coded_Picture_Width;
dst2+= Coded_Picture_Width;
}
}
#ifdef STORM
static void Dither_Bottom_Field420(unsigned char *src[],unsigned char *dst)
#else
static void Dither_Bottom_Field420(src,dst)
unsigned char *src[];
unsigned char *dst;
#endif
{
int i,j;
int Y1,Cb1,Cr1,Y2,Cb2,Cr2;
unsigned char *Y1_ptr,*Cb1_ptr,*Cr1_ptr,*Y2_ptr,*Cb2_ptr,*Cr2_ptr,*dst2;
Y2_ptr = Y1_ptr = src[0] + Coded_Picture_Width;
Cb2_ptr = Cb1_ptr = src[1] + Chroma_Width;
Cr2_ptr = Cr1_ptr = src[2] + Chroma_Width;
dst2 = dst;
for (j=0; j<Coded_Picture_Height; j+=4)
{
/* line j + 0, j + 1 */
for (i=0; i<Coded_Picture_Width; i+=4)
{
Y1 = *Y1_ptr++;
Y2 = *Y2_ptr++;
Cb1 = *Cb1_ptr++ >> 1;
Cr1 = *Cr1_ptr++ >> 1;
Cb2 = *Cb2_ptr++ >> 1;
Cr2 = *Cr2_ptr++ >> 1;
*dst++ = Pixel[Y_Table[((3*Y1+Y2)>>2)+15]|Cb_Table[((3*Cb1+Cb2)>>2)+15]
|Cr_Table[((3*Cr1+Cr2)>>2)+15]];
*dst2++ = Pixel[Y_Table[((Y1+3*Y2)>>2)]|Cb_Table[((Cb1+Cb2)>>1)]
|Cr_Table[((Cr1+Cr2)>>1)]];
Y1 = *Y1_ptr++;
Y2 = *Y2_ptr++;
*dst++ = Pixel[Y_Table[((3*Y1+Y2)>>2)+7]|Cb_Table[((3*Cb1+Cb2)>>2)+7]
|Cr_Table[((3*Cr1+Cr2)>>2)+7]];
*dst2++ = Pixel[Y_Table[((Y1+3*Y2)>>2)+8]|Cb_Table[((Cb1+Cb2)>>1)+8]
|Cr_Table[((Cr1+Cr2)>>1)+8]];
Y1 = *Y1_ptr++;
Y2 = *Y2_ptr++;
Cb1 = *Cb1_ptr++ >> 1;
Cr1 = *Cr1_ptr++ >> 1;
Cb2 = *Cb2_ptr++ >> 1;
Cr2 = *Cr2_ptr++ >> 1;
*dst++ = Pixel[Y_Table[((3*Y1+Y2)>>2)+13]|Cb_Table[((3*Cb1+Cb2)>>2)+13]
|Cr_Table[((3*Cr1+Cr2)>>2)+13]];
*dst2++ = Pixel[Y_Table[((Y1+3*Y2)>>2)+2]|Cb_Table[((Cb1+Cb2)>>1)+2]
|Cr_Table[((Cr1+Cr2)>>1)+2]];
Y1 = *Y1_ptr++;
Y2 = *Y2_ptr++;
*dst++ = Pixel[Y_Table[((3*Y1+Y2)>>2)+5]|Cb_Table[((3*Cb1+Cb2)>>2)+5]
|Cr_Table[((3*Cr1+Cr2)>>2)+5]];
*dst2++ = Pixel[Y_Table[((Y1+3*Y2)>>2)+10]|Cb_Table[((Cb1+Cb2)>>1)+10]
|Cr_Table[((Cr1+Cr2)>>1)+10]];
}
if (j!=0)
Y1_ptr += Coded_Picture_Width;
else
Y1_ptr -= Coded_Picture_Width;
Y2_ptr += Coded_Picture_Width;
Cb1_ptr -= Chroma_Width;
Cr1_ptr -= Chroma_Width;
Cb2_ptr -= Chroma_Width;
Cr2_ptr -= Chroma_Width;
if (j!=0)
dst += Coded_Picture_Width;
dst2 += Coded_Picture_Width;
/* line j + 2, j + 3 */
for (i=0; i<Coded_Picture_Width; i+=4)
{
Y1 = *Y1_ptr++;
Y2 = *Y2_ptr++;
Cb1 = *Cb1_ptr++ >> 1;
Cr1 = *Cr1_ptr++ >> 1;
Cb2 = *Cb2_ptr++ >> 1;
Cr2 = *Cr2_ptr++ >> 1;
*dst++ = Pixel[Y_Table[((3*Y1+Y2)>>2)+12]|Cb_Table[((Cb1+3*Cb2)>>2)+12]
|Cr_Table[((Cr1+3*Cr2)>>2)+12]];
*dst2++ = Pixel[Y_Table[((Y1+3*Y2)>>2)+3]|Cb_Table[Cb2+3]
|Cr_Table[Cr2+3]];
Y1 = *Y1_ptr++;
Y2 = *Y2_ptr++;
*dst++ = Pixel[Y_Table[((3*Y1+Y2)>>2)+4]|Cb_Table[((Cb1+3*Cb2)>>2)+4]
|Cr_Table[((Cr1+3*Cr2)>>2)+4]];
*dst2++ = Pixel[Y_Table[((Y1+3*Y2)>>2)+11]|Cb_Table[Cb2+11]
|Cr_Table[Cr2+11]];
Y1 = *Y1_ptr++;
Y2 = *Y2_ptr++;
Cb1 = *Cb1_ptr++ >> 1;
Cr1 = *Cr1_ptr++ >> 1;
Cb2 = *Cb2_ptr++ >> 1;
Cr2 = *Cr2_ptr++ >> 1;
*dst++ = Pixel[Y_Table[((3*Y1+Y2)>>2)+14]|Cb_Table[((Cb1+3*Cb2)>>2)+14]
|Cr_Table[((Cr1+3*Cr2)>>2)+14]];
*dst2++ = Pixel[Y_Table[((Y1+3*Y2)>>2)+1]|Cb_Table[Cb2+1]
|Cr_Table[Cr2+1]];
Y1 = *Y1_ptr++;
Y2 = *Y2_ptr++;
*dst++ = Pixel[Y_Table[((3*Y1+Y2)>>2)+6]|Cb_Table[((Cb1+3*Cb2)>>2)+6]
|Cr_Table[((Cr1+3*Cr2)>>2)+6]];
*dst2++ = Pixel[Y_Table[((Y1+3*Y2)>>2)+9]|Cb_Table[Cb2+9]
|Cr_Table[Cr2+9]];
}
Y1_ptr += Coded_Picture_Width;
Y2_ptr += Coded_Picture_Width;
if (j!=0)
{
Cb1_ptr += Chroma_Width;
Cr1_ptr += Chroma_Width;
}
else
{
Cb1_ptr -= Chroma_Width;
Cr1_ptr -= Chroma_Width;
}
Cb2_ptr += Chroma_Width;
Cr2_ptr += Chroma_Width;
dst += Coded_Picture_Width;
dst2+= Coded_Picture_Width;
}
Y2_ptr -= (Coded_Picture_Width<<1);
Cb2_ptr -= (Chroma_Width<<1);
Cr2_ptr -= (Chroma_Width<<1);
/* dither last line */
for (i=0; i<Coded_Picture_Width; i+=4)
{
Y1 = *Y1_ptr++;
Y2 = *Y2_ptr++;
Cb1 = *Cb1_ptr++ >> 1;
Cr1 = *Cr1_ptr++ >> 1;
Cb2 = *Cb2_ptr++ >> 1;
Cr2 = *Cr2_ptr++ >> 1;
*dst++ = Pixel[Y_Table[((3*Y1+Y2)>>2)+15]|Cb_Table[((3*Cb1+Cb2)>>2)+15]
|Cr_Table[((3*Cr1+Cr2)>>2)+15]];
Y1 = *Y1_ptr++;
Y2 = *Y2_ptr++;
*dst++ = Pixel[Y_Table[((3*Y1+Y2)>>2)+7]|Cb_Table[((3*Cb1+Cb2)>>2)+7]
|Cr_Table[((3*Cr1+Cr2)>>2)+7]];
Y1 = *Y1_ptr++;
Y2 = *Y2_ptr++;
Cb1 = *Cb1_ptr++ >> 1;
Cr1 = *Cr1_ptr++ >> 1;
Cb2 = *Cb2_ptr++ >> 1;
Cr2 = *Cr2_ptr++ >> 1;
*dst++ = Pixel[Y_Table[((3*Y1+Y2)>>2)+13]|Cb_Table[((3*Cb1+Cb2)>>2)+13]
|Cr_Table[((3*Cr1+Cr2)>>2)+13]];
Y1 = *Y1_ptr++;
Y2 = *Y2_ptr++;
*dst++ = Pixel[Y_Table[((3*Y1+Y2)>>2)+5]|Cb_Table[((3*Cb1+Cb2)>>2)+5]
|Cr_Table[((3*Cr1+Cr2)>>2)+5]];
}
}
#define twomerges1(a, b, c, d, shift, mask) \
{ \
temp1 = b; \
temp2 = d; \
temp1 >>= shift; \
temp2 >>= shift; \
temp1 ^= a; \
temp2 ^= c; \
temp1 &= mask; \
temp2 &= mask; \
a ^= temp1; \
c ^= temp2; \
temp1 <<= shift; \
temp2 <<= shift; \
b ^= temp1; \
d ^= temp2; \
}
#define twomerges2(a, b, c, d, shift, mask) \
{ \
temp1 = (a ^ (b >> shift)) & mask; \
temp2 = (c ^ (d >> shift)) & mask; \
a ^= temp1; \
c ^= temp2; \
b ^= temp1 << shift; \
d ^= temp2 << shift; \
}
void c2p1x1_8_c5_ppc(void *chunky, void *bitplanes,
int chunkyx, int chunkyy,
int xoffset, int yoffset,
int bitplanesize)
{
typedef unsigned long ULONG;
ULONG *c;
ULONG temp1, temp2;
ULONG *p0, *p1, *p2, *p3, *p4, *p5, *p6, *p7;
ULONG d0, d1, d2, d3, d4, d5, d6, d7;
ULONG t0, t1, t2, t3, t4, t5, t6, t7;
int i;
c = (ULONG *) chunky;
p0 = (ULONG *) (&(((char *) bitplanes)[yoffset * chunkyx >> 3]));
p1 = (ULONG *) (&(((char *) p0)[bitplanesize]));
p2 = (ULONG *) (&(((char *) p1)[bitplanesize]));
p3 = (ULONG *) (&(((char *) p2)[bitplanesize]));
p4 = (ULONG *) (&(((char *) p3)[bitplanesize]));
p5 = (ULONG *) (&(((char *) p4)[bitplanesize]));
p6 = (ULONG *) (&(((char *) p5)[bitplanesize]));
p7 = (ULONG *) (&(((char *) p6)[bitplanesize]));
i = chunkyx * chunkyy / (sizeof (ULONG) * 8);
d0 = *c++;
d1 = *c++;
d2 = *c++;
d3 = *c++;
d4 = *c++;
d5 = *c++;
d6 = *c++;
d7 = *c++;
twomerges1(d0, d4, d1, d5, 16, 0x0000ffff);
twomerges1(d2, d6, d3, d7, 16, 0x0000ffff);
twomerges1(d0, d2, d1, d3, 8, 0x00ff00ff);
twomerges1(d4, d6, d5, d7, 8, 0x00ff00ff);
twomerges1(d0, d1, d2, d3, 4, 0x0f0f0f0f);
twomerges1(d4, d5, d6, d7, 4, 0x0f0f0f0f);
twomerges1(d0, d4, d1, d5, 2, 0x33333333);
twomerges1(d2, d6, d3, d7, 2, 0x33333333);
twomerges1(d0, d2, d1, d3, 1, 0x55555555);
twomerges1(d4, d6, d5, d7, 1, 0x55555555);
t0 = d7;
t1 = d5;
t2 = d3;
t3 = d1;
t4 = d6;
t5 = d4;
t6 = d2;
t7 = d0;
while (--i)
{
d0 = *c++;
d1 = *c++;
d2 = *c++;
d3 = *c++;
d4 = *c++;
d5 = *c++;
d6 = *c++;
d7 = *c++;
*p0++ = t0;
twomerges1(d0, d4, d1, d5, 16, 0x0000ffff);
twomerges1(d2, d6, d3, d7, 16, 0x0000ffff);
*p1++ = t1;
twomerges1(d0, d2, d1, d3, 8, 0x00ff00ff);
twomerges1(d4, d6, d5, d7, 8, 0x00ff00ff);
*p2++ = t2;
twomerges1(d0, d1, d2, d3, 4, 0x0f0f0f0f);
twomerges1(d4, d5, d6, d7, 4, 0x0f0f0f0f);
*p3++ = t3;
twomerges1(d0, d4, d1, d5, 2, 0x33333333);
twomerges1(d2, d6, d3, d7, 2, 0x33333333);
*p4++ = t4;
twomerges1(d0, d2, d1, d3, 1, 0x55555555);
twomerges1(d4, d6, d5, d7, 1, 0x55555555);
*p5++ = t5;
*p6++ = t6;
*p7++ = t7;
t0 = d7;
t1 = d5;
t2 = d3;
t3 = d1;
t4 = d6;
t5 = d4;
t6 = d2;
t7 = d0;
}
*p0++ = t0;
*p1++ = t1;
*p2++ = t2;
*p3++ = t3;
*p4++ = t4;
*p5++ = t5;
*p6++ = t6;
*p7++ = t7;
}
#endif